import java.math.BigInteger;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class ElGamal {
    private BigInteger p, g, x, h;

    public ElGamal(int bitLength) {
        p = BigInteger.probablePrime(bitLength, new Random());
        g = findGenerator();
        x = new BigInteger(bitLength / 2, new Random());
        h = g.modPow(x, p);
    }

    private BigInteger findGenerator() {
        for (BigInteger i = new BigInteger("3"); i.compareTo(p) < 0; i = i.add(new BigInteger("2"))) {
            if (p.gcd(i).equals(BigInteger.ONE)) {
                return i;
            }
        }
        return null;
    }

    public BigInteger[] encrypt(BigInteger m) {
        BigInteger k = new BigInteger(m.bitLength(), new Random());
        BigInteger c1 = g.modPow(k, p);
        BigInteger c2 = m.multiply(h.modPow(k, p)).mod(p);
        return new BigInteger[]{c1, c2};
    }

    public BigInteger decrypt(BigInteger c1, BigInteger c2) {
        BigInteger s = c1.modPow(x, p);
        BigInteger m = c2.multiply(s.modInverse(p)).mod(p);
        return m;
    }

    public static void main(String[] args) {
        ElGamal elGamal = new ElGamal(512);
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入需要加密的信息：");
        String val = scanner.nextLine();
        BigInteger message = new BigInteger(val);
        BigInteger[] ciphertext = elGamal.encrypt(message);
        System.out.println("加密密文为: " + Arrays.toString(ciphertext));
        BigInteger decryptedMessage = elGamal.decrypt(ciphertext[0], ciphertext[1]);
        System.out.println("解密后为: " + decryptedMessage);
    }
}

